//************************************************
//  Filename      : first_level.v                             
//  Author        : Kingstacker                  
//  Company       : School                       
//  Email         : kingstacker_work@163.com     
//  Device        : Altera cyclone4 ep4ce6f17c8  
//  Description   :                              
//************************************************
module  eight_level #(parameter WIDTH = 16)(
    //input;
    input    wire    clk,
    input    wire    rst_n,
    input    wire    signed [WIDTH-1:0] xin,
    //output;
    output   reg    signed [WIDTH-1:0] yout  
);
reg signed [WIDTH-1:0] xin1;
reg signed [WIDTH-1:0] xin2;
wire signed [31:0] mul_0; 
wire signed [31:0] mul_1; 
wire signed [31:0] mul_2; 
wire signed [33:0] xsum;
reg signed [WIDTH-1:0] yin1;
reg signed [WIDTH-1:0] yin2;
wire signed [31:0] mul_3;
wire signed [31:0] mul_4;
wire signed [32:0] ysum;
wire signed [33:0] ysult;
wire signed [33:0] ydiv;
wire signed [WIDTH-1:0] yin;
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        xin1 <= 0;
        xin2 <= 0;
    end //if
    else begin
        xin1 <= xin;    
        xin2 <= xin1;    
    end //else
end //always
assign mul_0 = {{{3{xin[15]}},xin,13'd0}+{{4{xin[15]}},xin,12'd0}+{{7{xin[15]}},xin,9'd0}+{{9{xin[15]}},xin,7'd0}+{{13{xin[15]}},xin,3'd0}+{{16{xin[15]}},xin}};
assign mul_1 = {-{{1{xin1[15]}},xin1,15'd0}+{{4{xin1[15]}},xin1,12'd0}+{{5{xin1[15]}},xin1,11'd0}+{{7{xin1[15]}},xin1,9'd0}+{{8{xin1[15]}},xin1,8'd0}+{{11{xin1[15]}},xin1,5'd0}+{{15{xin1[15]}},xin1,1'd0}};
assign mul_2 = {{{3{xin2[15]}},xin2,13'd0}+{{4{xin2[15]}},xin2,12'd0}+{{7{xin2[15]}},xin2,9'd0}+{{9{xin2[15]}},xin2,7'd0}+{{13{xin2[15]}},xin2,3'd0}+{{16{xin2[15]}},xin2}};
assign xsum  = mul_0 + mul_1 + mul_2;
//
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        yin1 <= 0;
        yin2 <= 0;
    end //if
    else begin
        yin1 <= yin;
        yin2 <= yin1;    
    end //else
end //always
assign mul_3 = {-{{1{yin1[15]}},yin1,15'd0}+{{9{yin1[15]}},yin1,7'd0}+{{12{yin1[15]}},yin1,4'd0}};
assign mul_4 = {{{2{yin2[15]}},yin2,14'd0}-{{11{yin2[15]}},yin2,5'd0}-{{13{yin2[15]}},yin2,3'd0}-{{15{yin2[15]}},yin2,1'd0}-{{16{yin2[15]}},yin2}};
assign ysum  = mul_3 + mul_4;
assign ysult = xsum - ysum;   
assign ydiv  = {{14{ysult[33]}},ysult[33:14]}; 
assign yin = ((~rst_n)? 16'd0 : ydiv[15:0]);
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        yout <= 0;
    end //if
    else begin
        yout <= yin;    
    end //else
end //always
endmodule